home *** CD-ROM | disk | FTP | other *** search
Text File | 1988-11-14 | 73.3 KB | 3,261 lines |
- head 2.12;
- branch ;
- access ;
- symbols ;
- locks ; strict;
- comment @ * @;
-
-
- 2.12
- date 88.06.23.11.46.48; author douglis; state Exp;
- branches ;
- next 2.11;
-
- 2.11
- date 88.06.17.14.17.50; author douglis; state Exp;
- branches ;
- next 2.10;
-
- 2.10
- date 88.05.15.20.44.42; author douglis; state Exp;
- branches ;
- next 2.9;
-
- 2.9
- date 88.04.07.10.29.06; author douglis; state Exp;
- branches ;
- next 2.8;
-
- 2.8
- date 88.03.17.22.42.45; author douglis; state Exp;
- branches ;
- next 2.7;
-
- 2.7
- date 88.02.21.15.54.34; author douglis; state Exp;
- branches ;
- next 2.6;
-
- 2.6
- date 87.12.02.12.02.46; author douglis; state Exp;
- branches ;
- next 2.5;
-
- 2.5
- date 87.12.01.20.52.50; author douglis; state Exp;
- branches ;
- next 2.4;
-
- 2.4
- date 87.11.20.12.40.01; author douglis; state Exp;
- branches ;
- next 2.3;
-
- 2.3
- date 87.11.19.19.52.47; author douglis; state Exp;
- branches ;
- next 2.2;
-
- 2.2
- date 87.03.15.21.33.15; author douglis; state Exp;
- branches ;
- next 2.1;
-
- 2.1
- date 87.03.11.18.12.13; author douglis; state Exp;
- branches ;
- next 2.0;
-
- 2.0
- date 87.03.11.12.39.41; author douglis; state Exp;
- branches ;
- next 1.8;
-
- 1.8
- date 87.03.11.11.09.50; author douglis; state Exp;
- branches ;
- next 1.7;
-
- 1.7
- date 87.03.09.12.14.30; author douglis; state Exp;
- branches ;
- next 1.6;
-
- 1.6
- date 87.03.03.14.57.39; author douglis; state Exp;
- branches ;
- next 1.5;
-
- 1.5
- date 87.02.23.20.13.41; author douglis; state Exp;
- branches ;
- next 1.4;
-
- 1.4
- date 87.02.19.15.47.20; author douglis; state Exp;
- branches ;
- next 1.3;
-
- 1.3
- date 87.02.19.15.17.17; author douglis; state Exp;
- branches ;
- next 1.2;
-
- 1.2
- date 87.02.15.22.31.46; author douglis; state Exp;
- branches ;
- next 1.1;
-
- 1.1
- date 87.02.15.20.53.15; author douglis; state Exp;
- branches ;
- next ;
-
-
- desc
- @Maintain load average information on a per-host basis. This program
- may be invoked as a daemon (to update global state on a regular basis)
- or as a stand-alone program (to return the load of the local host).
- @
-
-
- 2.12
- log
- @removed some old flags
- @
- text
- @/*
- * loadAvg.c --
- *
- * Maintain load average information on a per-host basis. This program
- * may be invoked as a daemon (to update global state on a regular basis)
- * or as a stand-alone program (to return the load of the local host or
- * all hosts on the network).
- *
- * Copyright 1987 Regents of the University of California
- * All rights reserved.
- */
-
- #ifndef lint
- static char rcsid[] = "$Header: loadAvg.c,v 2.11 88/06/17 14:17:50 douglis Exp $ SPRITE (Berkeley)";
- #endif not lint
-
-
- #include "loadAvg.h"
- #include "sys.h"
- #include "option.h"
- #include "rand.h"
- #include "string.h"
- #include "syslog.h"
- #include "host.h"
-
- /*
- * Define constants for defaults values of variables that may be assigned
- * by command-line arguments.
- */
-
- /*
- * Constants specific to gathering load average statistics. (The weights may
- * be modified with -D options but are not user-specifiable on the
- * command line.) The LOAD_INTERVAL is the number of seconds between sampling
- * the utilization and ready queue lengths, and the WRITE_INTERVAL is the
- * maximum number of seconds that may pass between updating the shared data
- * file. (The private data file is updated on each iteration.)
- * For example, to write once per minute if the state of a machine doesn't
- * change between idle and inUse, WRITE_INTERVAL would be (12 * LOAD_INTERVAL).
- * To write every time, set it equal to LOAD_INTERVAL. TIME_OUT is the
- * default time to allow a host before assuming it's down.
- */
-
- #define LOAD_INTERVAL 5
- #define WRITE_INTERVAL (12 * LOAD_INTERVAL)
- #define TIME_OUT 180
-
- #define WEIGHT1 (double) 0.9200444146293232 /* exp(-1/12) */
- #define WEIGHT2 (double) 0.9834714538216174 /* exp(-1/60) */
- #define WEIGHT3 (double) 0.9944598480048967 /* exp(-1/180) */
-
- double weights[] = {WEIGHT1, WEIGHT2, WEIGHT3};
-
-
- /*
- * Define arbitrary thresholds (see loadAvg.h).
- *
- * All load values must be below THRESHOLD_LOW to start accepting foreign
- * processes, but once they are being accepted, there are different
- * thresholds for each average: if any one of them is exceeded, stop
- * aceepting foreign processes.
- *
- * INPUT_THRESHOLD is the number of seconds that a node must
- * be idle for it to accept migrated processes. (Set to a low value for
- * testing.)
- */
-
-
- #define THRESHOLD_LOW 0.3
- #define THRESHOLD_HIGH0 2.0
- #define THRESHOLD_HIGH1 1.0
- #define THRESHOLD_HIGH2 0.5
- #define INPUT_THRESHOLD 30
-
- Thresholds thresholds = {
- INPUT_THRESHOLD,
- {THRESHOLD_LOW, THRESHOLD_LOW, THRESHOLD_LOW},
- {THRESHOLD_HIGH0, THRESHOLD_HIGH1, THRESHOLD_HIGH2}
- };
-
- Boolean allHosts = FALSE;
- Boolean getLoad = FALSE;
- Boolean runDaemon = FALSE;
- Boolean debug = FALSE;
- Boolean verbose = FALSE;
- int loadInterval = LOAD_INTERVAL;
- int writeInterval = WRITE_INTERVAL;
- int timeOut = TIME_OUT;
- Boolean getIdleNode = FALSE;
- Boolean forkChild = FALSE;
- Boolean zapHostInfo = FALSE;
-
- /*
- * Both of these are temporary areas to hold changes in the default values.
- * If untouched by options, then they aren't used. (LowThreshold is
- * replicated in thresholds.min[0..2].)
- */
-
- double lowThreshold = THRESHOLD_LOW;
- char *thresholdString = NULL;
-
- char *myName = NULL;
-
- Option optionArray[] = {
- {OPT_TRUE, 'a', (Address)&allHosts,
- "Get the load average of all nodes (DEFAULT for 'rup')."},
- {OPT_TRUE, 'l', (Address)&getLoad,
- "Get the load average of this node (DEFAULT for 'loadAvg')."},
- {OPT_TRUE, 'i', (Address)&getIdleNode,
- "Get the hostID of an idle node."},
- {OPT_TRUE, 'd', (Address)&runDaemon,
- "Run as a daemon and report load information to the global file."},
- {OPT_TRUE, 'D', (Address)&debug, "Enable debugging information."},
- {OPT_TRUE, 'v', (Address)&verbose,
- "Report to stderr when no idle nodes available."},
- {OPT_INT, 'I', (Address)&loadInterval,
- "Interval between iterations for getting load info."},
- {OPT_INT, 'w', (Address)&writeInterval,
- "Maximum interval between outputting load info."},
- {OPT_INT, 'W', (Address)&timeOut,
- "Maximum time during which info is valid without update."},
- {OPT_TRUE, 'F', (Address)&forkChild, "Fork off daemons."},
- {OPT_INT, 'N', (Address)&thresholds.noInput,
- "Minimum idle time to allow foreign procs."},
- {OPT_FLOAT, 't', (Address)&lowThreshold,
- "Maximum load average to allow foreign procs."},
- {OPT_STRING, 'T', (Address)&thresholdString,
- "Set of maximum thresholds before refusing migration, once allowed (as in the form '-T \"0.5 1.0 2.0\"')."},
- {OPT_TRUE, 'Z', (Address)&zapHostInfo,
- "Zap (remove) the information for hosts specified as remaining arguments."},
- };
- static int numOptions = sizeof(optionArray) / sizeof(Option);
-
- typedef enum {
- DOWN,
- UP,
- IDLE
- } MachineState;
-
- /*
- * Global variables.
- */
- Time currentTime;
- int hostID;
- int archType;
-
-
- static void ListHosts();
- static void OutputStatus();
- static void ZapHostInfo();
- static char *UpString();
-
-
-
- /*
- *----------------------------------------------------------------------
- *
- * Main --
- *
- * The driver for the loadAvg program. Parse options and invoke
- * subroutines as appropriate.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The global var. 'hostID' is initialized.
- *
- *----------------------------------------------------------------------
- */
-
- int
- main(argc, argv)
- int argc;
- char *argv[];
- {
- register ReturnStatus status = SUCCESS;
- int numScanned;
- int i;
- int host;
- Host_Info info;
-
-
- status = Opt_Parse(&argc, argv, numOptions, optionArray);
- if (status != SUCCESS) {
- Stat_PrintMsg(status, "Error in Opt_Parse");
- Proc_Exit(status);
- }
-
- myName = argv[0];
-
- /*
- * Process interrelated defaults and perform sanity checking on
- * arguments.
- */
-
- /*
- * Default operation is to get the local load, using a global data file.
- */
-
- if (! (runDaemon || getIdleNode || getLoad || zapHostInfo)) {
- if (String_FindSubstring(myName, "rup") != NULL) {
- getLoad = TRUE;
- allHosts = TRUE;
- } else {
- getLoad = TRUE;
- }
- }
-
- if (lowThreshold != THRESHOLD_LOW) {
- for (i = 0; i < LOAD_NUM_VALUES; i++) {
- thresholds.min[i] = lowThreshold;
- }
- }
-
- if (thresholdString) {
- numScanned = Io_ScanString(thresholdString, "%lf %lf %lf",
- &thresholds.max[0], &thresholds.max[1],
- &thresholds.max[2]);
- if (numScanned < 3) {
- Io_PrintStream(io_StdErr, "%s: Invalid thresholds '%s'.\n",
- thresholdString);
- Proc_Exit(FAILURE);
- }
- }
-
- if (writeInterval < loadInterval) {
- writeInterval = loadInterval;
- }
-
- if (debug && runDaemon) {
- Io_PrintStream(io_StdErr, "Weights are %f, %f, %f.\n",
- weights[0], weights[1], weights[2]);
- }
-
- /*
- * Initialize global variables.
- */
- status = Sys_GetMachineInfo(&archType, NULL, &hostID);
- if (status != SUCCESS) {
- syslog(LOG_ERR, "%s: Error in Sys_GetMachineInfo: %s\n", myName,
- Stat_GetMsg(status));
- Proc_Exit(status);
- }
- status = Sys_GetTimeOfDay(¤tTime, NULL, NULL);
- if (status != SUCCESS) {
- syslog(LOG_ERR, "%s: Error in Sys_GetTimeOfDay: %s\n", myName,
- Stat_GetMsg(status));
- Proc_Exit(status);
- }
-
- if (debug) {
- Io_PrintStream(io_StdErr, "My hostID is %d.\n", hostID);
- }
-
- if (zapHostInfo) {
- for (i = 1; i < argc; i++) {
- ZapHostInfo(argv[i]);
- }
- }
- if (runDaemon) {
- RunDaemon();
- }
- if (getIdleNode) {
- status = Host_GetIdleNode(&host);
- if (status == SUCCESS) {
- Io_Print("%d\n", host);
- } else if (verbose) {
- Io_PrintStream(io_StdErr, "No idle node found.\n");
- }
- }
- if (getLoad) {
- if (allHosts) {
- ListHosts();
- } else {
- status = Host_GetInfo((int) PROC_MY_HOSTID, &info);
- if (status != SUCCESS) {
- Stat_PrintMsg(status, "Error in Host_GetInfo");
- Proc_Exit(status);
- }
- OutputStatus(&info);
- }
- }
-
- Proc_Exit(status);
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * ListHosts --
- *
- * Output the load average and status of all nodes.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The data are is written to io_StdOut.
- *
- *----------------------------------------------------------------------
- */
-
- static void
- ListHosts()
- {
- int numRecs;
- ReturnStatus status;
- register Host_Info *infoPtr;
- Host_Info *infoArray;
- int i;
- int maxSize;
-
- if (debug) {
- Io_PrintStream(io_StdErr, "ListHosts called.\n");
- Io_Flush(io_StdErr);
- }
-
- maxSize = MAX_NUM_HOSTS * sizeof(Host_Info);
- infoArray = (Host_Info *) Mem_Alloc(maxSize);
- status = Host_GetAllInfo(MAX_NUM_HOSTS, infoArray, &numRecs);
- if (status != SUCCESS) {
- Stat_PrintMsg(status, "Error in Host_GetAllInfo");
- Proc_Exit(status);
- }
- if (debug && numRecs == 0) {
- Io_PrintStream(io_StdErr, "No host records found.\n");
- Io_Flush(io_StdErr);
- return;
- }
-
-
- for (i = 0; i < numRecs; i++) {
- infoPtr = &infoArray[i];
- if (infoPtr->timestamp != 0) {
- if (i != infoPtr->hostID) {
- Io_PrintStream(io_StdErr,
- "ListHosts: mismatch between counter (%d) and value in data file (%d).\n",
- i, infoPtr->hostID);
- Proc_Exit(FAILURE);
- }
- OutputStatus(infoPtr);
- }
- }
- Mem_Free((Address) infoArray);
- }
-
-
-
- /*
- *----------------------------------------------------------------------
- *
- * OutputStatus --
- *
- * Determine the status of the given host and write a "ruptime"-like
- * record to stdout.
- *
- * Results:
- * None.
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- #define HOST_NAME_SIZE 64
- #define TIME_STR_LEN 13
- #define SECOND_OFFSET 9
-
- static void
- OutputStatus(infoPtr)
- register Host_Info *infoPtr;
- {
- MachineState state;
- static char hostname[HOST_NAME_SIZE];
- static char idleTime[TIME_STR_LEN];
- ReturnStatus status;
- char *upStr;
-
- /*
- * NOTE: the order of arguments here corresponds to the implementation
- * of this routine, not to the man page!!
- */
- status = Sys_GetHostNameByID(infoPtr->hostID, HOST_NAME_SIZE, hostname);
- if (status != SUCCESS) {
- syslog(LOG_ERR, "%s: Sys_GetHostnameByID: %s\n", myName,
- Stat_GetMsg(status));
- Proc_Exit(status);
- }
-
- upStr = UpString(infoPtr->timestamp, infoPtr->bootTime, &state);
-
- /*
- * We allow migration if the file says to allow it, UpString indicated
- * that the entry in the file is current, and it is the same machine type.
- */
- if (state == UP && infoPtr->allowMigration &&
- infoPtr->archType == archType) {
- state = IDLE;
- }
- Io_PrintStream(io_StdOut,
- "%24s%1s %s %s",
- hostname, (state == IDLE) ? "*" : "",
- (state == DOWN) ? "down" : " up",
- upStr);
- if (state != DOWN) {
- Time_ToAscii(infoPtr->noInput, TRUE, idleTime);
- Io_PrintStream(io_StdOut,
- " %5.2lf %5.2lf %5.2lf (idle %s)",
- infoPtr->lengths[0], infoPtr->lengths[1],
- infoPtr->lengths[2], idleTime);
- }
- Io_PrintStream(io_StdOut, "\n");
- }
-
- static char *
- UpString(modTime, bootTime, statePtr)
- int modTime;
- int bootTime;
- MachineState *statePtr;
- {
- static char timeStr[TIME_STR_LEN];
- int diff;
-
- *statePtr = UP;
- /*
- * See if the entry is out of date. (Assume that anything updated
- * after the current time is fairly recent and is caused by clock
- * skew, so negative diffs are okay.)
- */
- diff = currentTime.seconds - modTime;
- if (diff > timeOut) {
- *statePtr = DOWN;
- } else {
- /*
- * Now we want to know how long the machine has been up.
- */
- diff = modTime - bootTime;
- if (diff < 0) {
- Io_PrintStream(io_StdErr,
- "Change was made before boot time?? modTime %d, bootTime %d.\n",
- modTime, bootTime);
- *statePtr = DOWN;
- diff = 0;
- }
- }
-
-
- Time_ToAscii(diff, TRUE, timeStr);
- timeStr[SECOND_OFFSET] = '\0';
- return(timeStr);
- }
-
-
-
- /*
- *----------------------------------------------------------------------
- *
- * ZapHostInfo --
- *
- * Zero out the information for a host.
- *
- * Results:
- * None.
- *
- * Side effects:
- * The global database is modified.
- *
- *----------------------------------------------------------------------
- */
-
- static void
- ZapHostInfo(hostName)
- char *hostName;
- {
- ReturnStatus status;
- Host_Info info;
- Host_Entry *hostPtr;
- DB_Handle sharedHandle;
-
-
- hostPtr = Host_ByName(hostName);
- if (hostPtr == (Host_Entry *) NULL) {
- Io_PrintStream(io_StdErr, "ZapHostInfo: couldn't get info for %s.\n",
- hostName);
- return;
- }
- if (debug) {
- Io_PrintStream(io_StdErr, "Opening shared database.\n");
- Io_Flush(io_StdErr);
- }
- /*
- * If a lock is broken, GEN_TIMEOUT is returned, and we will ignore
- * that error.
- */
- status = Host_OpenInfo(HOST_INFO_SHARED, TRUE, &sharedHandle);
- if (status != SUCCESS && status != GEN_TIMEOUT) {
- Stat_PrintMsg(status, "Error in Host_OpenInfo (shared)");
- Proc_Exit(status);
- } else if (status == GEN_TIMEOUT) {
- syslog(LOG_WARNING, "Broke lock for shared data file");
- }
- Byte_Zero(sizeof(info), (Address) &info);
- status = Host_UpdateInfo(hostPtr->id, &info, &sharedHandle);
- if (status != SUCCESS) {
- syslog(LOG_ERR,
- "Error %x returned from Host_UpdateInfo (shared)",
- status);
- Proc_Exit(status);
- }
- status = DB_Close(&sharedHandle);
- if (status != SUCCESS) {
- Io_PrintStream(io_StdErr, "%s: ZapHostInfo: error in DB_Close: %s\n",
- myName, Stat_GetMsg(status));
- Proc_Exit(status);
- }
- }
- @
-
-
- 2.11
- log
- @Split into private and shared data files, updated at different rates.
- Private used for xload, shared for migration & such. Changed to use
- libc Host_* procedures.
- @
- text
- @d14 1
- a14 1
- static char rcsid[] = "$Header: loadAvg.c,v 2.10 88/05/15 20:44:42 douglis Exp $ SPRITE (Berkeley)";
- a90 1
- Boolean lockFile = TRUE;
- a91 1
- char *dataFile = "/sprite/spool/loadAvg/utilization";
- d115 1
- a115 1
- "Output load information in verbose form."},
- a122 4
- {OPT_FALSE, 'L', (Address)&lockFile,
- "Do not lock data file during use."},
- {OPT_STRING, 'o', (Address)&dataFile,
- "File name to write data."},
- @
-
-
- 2.10
- log
- @changed to use the hostInfo C library routines and structures.
- @
- text
- @d14 1
- a14 1
- static char rcsid[] = "$Header: loadAvg.c,v 2.9 88/04/07 10:29:06 douglis Exp $ SPRITE (Berkeley)";
- d36 2
- a37 1
- * maximum number of seconds that may pass between updating the data file.
- d45 1
- a45 1
- #define WRITE_INTERVAL LOAD_INTERVAL
- d154 2
- a155 1
- static void GetLoad();
- a157 1
- static MachineState GetStatus();
- d186 3
- d271 6
- a276 1
- GetLoad(TRUE);
- d279 10
- a288 1
- GetLoad(FALSE);
- d298 1
- a298 1
- * GetLoad --
- d300 1
- a300 2
- * Output the load average of this node, all nodes, or of an idle
- * node. If getting idle node and not verbose, just output hostID.
- a307 3
- * Restriction: looking up this host only works for the shared file format
- * for now, but that's the only way we're using it now.
- *
- d312 1
- a312 2
- GetLoad(getIdle)
- Boolean getIdle; /* if TRUE, pick an idle node at random */
- a313 1
- int bytesRead;
- a315 1
- int streamID;
- a319 4
- MachineState state;
- Boolean output;
- int possibleHosts[MAX_NUM_HOSTS];
- int numPossible = 0;
- d322 1
- a322 1
- Io_PrintStream(io_StdErr, "GetLoad called.\n");
- d336 1
- d345 1
- a345 1
- "GetLoad: mismatch between counter (%d) and value in data file (%d).\n",
- d349 1
- a349 10
- if (!getIdle && (allHosts || i == hostID)) {
- output = TRUE;
- } else {
- output = FALSE;
- }
- state = GetStatus(infoPtr, output);
- if (state == IDLE) {
- possibleHosts[numPossible] = i;
- numPossible += 1;
- }
- a351 3
- if (verbose) {
- Io_Flush(io_StdErr);
- }
- a352 22
- if (!getIdle) {
- return;
- }
- if (debug) {
- Io_PrintStream(io_StdErr, "There are %d possible idle hosts.\n",
- numPossible);
- Io_Flush(io_StdErr);
- }
- if (numPossible > 0) {
- int randNum;
-
- Rand_InitSeed((unsigned) currentTime.microseconds);
- if (numPossible > 1) {
- randNum = Rand_GetValue();
- randNum = randNum % numPossible;
- } else {
- randNum = 0;
- }
- Io_Print("%d\n", possibleHosts[randNum]);
- } else {
- Io_Print("0\n");
- }
- d360 1
- a360 1
- * GetStatus --
- d362 2
- a363 2
- * Determine the status of the given host;
- * if output is specified, write a "ruptime"-like record to stdout.
- d366 1
- a366 1
- * TRUE if it is permissible to migrate to the given host.
- d378 2
- a379 2
- static MachineState
- GetStatus(infoPtr, output)
- a380 1
- Boolean output;
- d402 2
- a403 2
- * We allow migration if the file says to allow it and UpString indicated
- * that the entry in the file is current.
- d405 2
- a406 1
- if (state == UP && infoPtr->allowMigration) {
- d409 7
- a415 1
- if (output) {
- d417 3
- a419 12
- "%24s%1s %s %s %s",
- hostname, (state == IDLE) ? "*" : "",
- (state == DOWN) ? "down" : " up",
- upStr);
- if (state != DOWN) {
- Time_ToAscii(infoPtr->noInput, TRUE, idleTime);
- Io_PrintStream(io_StdOut,
- " %5.2lf %5.2lf %5.2lf (idle %s)",
- infoPtr->lengths[0], infoPtr->lengths[1],
- infoPtr->lengths[2], idleTime);
- }
- Io_PrintStream(io_StdOut, "\n");
- d421 1
- a421 1
- return(state);
- a460 19
-
- /*
- *----------------------------------------------------------------------
- *
- * OpenCreate --
- *
- * Perform an Fs_Open on a file, creating it if necessary. (This
- * routine is needed because simply passing in FS_CREATE will cause
- * existing files to be truncated.)
- *
- * Results:
- * The return status from Fs_Open is returned. A stream ID is returned
- * in *streamIDPtr.
- *
- * Side effects:
- * A file is opened, and it is created if it doesn't exist.
- *
- *----------------------------------------------------------------------
- */
- a461 18
- ReturnStatus
- OpenCreate(pathName, usageFlags, permissions, streamIDPtr)
- char *pathName; /* The name of the file to open */
- int usageFlags; /* FS_READ, FS_WRITE, FS_CREATE, FS_TRUNC */
- int permissions; /* Permission mask to use on creation */
- int *streamIDPtr; /* This is the user's handle on the open
- * file used in later filesystem requests */
- {
- ReturnStatus status;
-
- status = Fs_Open(pathName, usageFlags, permissions, streamIDPtr);
- if (status == FS_FILE_NOT_FOUND) {
- status = Fs_Open(pathName, usageFlags | FS_CREATE, permissions,
- streamIDPtr);
- }
- return(status);
- }
-
- a484 1
- int streamID;
- a485 1
- int bytesWritten;
- d487 1
- a487 1
- int offset;
- d497 1
- a497 3
- Io_PrintStream(io_StdErr,
- "ZapHostInfo: hostID %d. Opening file %s.\n",
- hostPtr->id, dataFile);
- d500 7
- a506 4
- status = Fs_Open(dataFile, FS_WRITE, 0, &streamID);
- if (status != SUCCESS) {
- Io_PrintStream(io_StdErr, "%s: ZapHostInfo: error opening data file: %s\n",
- myName, Stat_GetMsg(status));
- d508 2
- a510 13
- if (lockFile) {
- if (debug) {
- Io_PrintStream(io_StdErr, "ZapHostInfo: calling Ioc_Lock.\n");
- Io_Flush(io_StdErr);
- }
- status = Ioc_Lock(streamID, IOC_LOCK_EXCLUSIVE);
- if (status != SUCCESS) {
- syslog(LOG_ERR, "%s: ZapHostInfo: error in Ioc_Lock: %s\n",
- myName, Stat_GetMsg(status));
- Proc_Exit(status);
- }
- }
-
- d512 1
- a512 2
- offset = hostPtr->id * sizeof(info);
- status = Ioc_Reposition(streamID, IOC_BASE_ZERO, offset, (int *) NULL);
- d514 3
- a516 2
- Io_PrintStream(io_StdErr, "%s: OutputLoads: error in Ioc_Reposition: %s\n",
- myName, Stat_GetMsg(status));
- d519 1
- a519 1
- status = Fs_Write(streamID, sizeof(info), (Address) &info, &bytesWritten);
- d521 1
- a521 19
- Io_PrintStream(io_StdErr, "%s: ZapHostInfo: error in Fs_Read: %s\n",
- myName, Stat_GetMsg(status));
- Proc_Exit(status);
- }
- if (lockFile) {
- if (debug) {
- Io_PrintStream(io_StdErr, "ZapHostInfo: calling Ioc_Unlock.\n");
- Io_Flush(io_StdErr);
- }
- status = Ioc_Unlock(streamID, IOC_LOCK_EXCLUSIVE);
- if (status != SUCCESS) {
- Stat_PrintMsg(status,
- "ZapHostInfo: error in Ioc_Unlock");
- Proc_Exit(status);
- }
- }
- status = Fs_Close(streamID);
- if (status != SUCCESS) {
- Io_PrintStream(io_StdErr, "%s: ZapHostInfo: error in Fs_Close: %s\n",
- @
-
-
- 2.9
- log
- @Removed references to "server" and using pipes, since that's obsolete.
- @
- text
- @d14 1
- a14 1
- static char rcsid[] = "$Header: loadAvg.c,v 2.8 88/03/17 22:42:45 douglis Exp $ SPRITE (Berkeley)";
- d34 7
- a40 1
- * command line.)
- d44 2
- a45 2
- #define WRITE_INTERVAL (12 * LOAD_INTERVAL)
- #define TIME_OUT (3 * WRITE_INTERVAL)
- d305 2
- a306 2
- register NodeInfo *infoPtr;
- NodeInfo *infoArray;
- d319 3
- a321 6
- if (debug) {
- Io_PrintStream(io_StdErr, "GetLoad: opening file %s.\n",
- dataFile);
- Io_Flush(io_StdErr);
- }
- status = Fs_Open(dataFile, FS_READ, 0, &streamID);
- d323 1
- a323 2
- syslog(LOG_ERR, "%s: GetLoad: error opening data file: %s\n",
- myName, Stat_GetMsg(status));
- d326 3
- a328 11
- if (lockFile) {
- if (debug) {
- Io_PrintStream(io_StdErr, "GetLoad: calling Ioc_Lock.\n");
- Io_Flush(io_StdErr);
- }
- status = Ioc_Lock(streamID, IOC_LOCK_EXCLUSIVE);
- if (status != SUCCESS) {
- syslog(LOG_ERR, "%s: GetLoad: error in Ioc_Lock: %s\n",
- myName, Stat_GetMsg(status));
- Proc_Exit(status);
- }
- d330 1
- a330 6
- maxSize = MAX_NUM_HOSTS * sizeof(NodeInfo);
- infoArray = (NodeInfo *) Mem_Alloc(maxSize);
- if (debug) {
- Io_PrintStream(io_StdErr, "GetLoad: calling Fs_Read.\n");
- Io_Flush(io_StdErr);
- }
- a331 20
- status = Fs_Read(streamID, maxSize, (Address) infoArray, &bytesRead);
- if (status != SUCCESS) {
- syslog(LOG_ERR, "%s: GetLoad: error in Fs_Read: %s\n", myName,
- Stat_GetMsg(status));
- Proc_Exit(status);
- }
- if (lockFile) {
- if (debug) {
- Io_PrintStream(io_StdErr, "GetLoad: calling Ioc_Unlock.\n");
- Io_Flush(io_StdErr);
- }
- status = Ioc_Unlock(streamID, IOC_LOCK_EXCLUSIVE);
- if (status != SUCCESS) {
- Stat_PrintMsg(status,
- "GetLoad: error in Ioc_Unlock");
- Proc_Exit(status);
- }
- }
- numRecs = bytesRead / sizeof(NodeInfo);
-
- d406 1
- a406 1
- register NodeInfo *infoPtr;
- d552 1
- a552 1
- NodeInfo info;
- @
-
-
- 2.8
- log
- @Added -Z flag to zap hostname info.
- @
- text
- @d14 1
- a14 1
- static char rcsid[] = "$Header: loadAvg.c,v 2.7 88/02/21 15:54:34 douglis Exp $ SPRITE (Berkeley)";
- a76 1
- Boolean runServer = FALSE;
- a81 2
- Boolean useDataFile = FALSE;
- Boolean usePipes = FALSE;
- a85 3
- char *pipeDir = "/sprite/spool/loadAvg/daemons";
- char *requestFile = "globalLoad.request";
- char *responseFile = "globalLoad.response";
- d107 1
- a107 3
- "Run as a daemon and report load information to the global file/server."},
- {OPT_TRUE, 's', (Address)&runServer,
- "Run as a global server maintaining global state."},
- a117 4
- {OPT_TRUE, 'f', (Address)&useDataFile,
- "Output options:\n\tUse shared data file for global load information (DEFAULT)."},
- {OPT_TRUE, 'p', (Address)&usePipes,
- "\tUse named pipes for global load information."},
- d119 1
- a119 1
- "Do not lock data file during use (ignored with -p option)."},
- a121 6
- {OPT_STRING, 'P', (Address)&pipeDir,
- "Directory containing named pipes."},
- {OPT_STRING, 'r', (Address)&requestFile,
- "Request named pipe name."},
- {OPT_STRING, 'R', (Address)&responseFile,
- "Response pipe name."},
- a192 9
- if (! (useDataFile || usePipes)) {
- useDataFile = TRUE;
- } else if (useDataFile && usePipes) {
- Io_PrintStream(io_StdErr,
- "%s: may only write to one of data-file or pipe.\n",
- myName);
- Proc_Exit(FAILURE);
- }
-
- d197 1
- a197 1
- if (! (runServer || runDaemon || getIdleNode || getLoad || zapHostInfo)) {
- a204 6
- if (lockFile && !useDataFile) {
- Io_PrintStream(io_StdErr,
- "%s: may only specify lock (-l) option if writing to a data file.\n",
- myName);
- Proc_Exit(FAILURE);
- }
- a259 3
- if (runServer) {
- RunServer();
- }
- a294 2
- static char utilRecord[UTIL_RECORD_SIZE];
- int bytesWritten;
- a295 2
- char *utilPtr;
- char *utilsPtr;
- a297 1
- char fileName[FS_MAX_PATH_NAME_LENGTH];
- a298 1
- NodeInfo nodeInfo;
- a302 2
- double lowestLoad;
- int numScanned;
- d310 6
- d318 7
- a324 7
-
- if (usePipes) {
- if (getLoad) {
- Sys_Panic(SYS_FATAL, "Can't get load average of local host when using pipes (yet).");
- }
- Io_PrintString(utilRecord, "%2d\n", LA_RPC_IDLE);
- Io_PrintString(fileName, "%s/%s", pipeDir, requestFile);
- d326 1
- a326 1
- Io_PrintStream(io_StdErr, "GetLoad: opening file %s.\n", fileName);
- d329 1
- a329 2
- status = OpenCreate(fileName, (FS_WRITE | FS_NAMED_PIPE_OPEN),
- OPEN_MODE, &streamID);
- d331 2
- a332 2
- syslog(LOG_ERR, "%s: GetLoad: error in Fs_Open: %s\n", myName,
- Stat_GetMsg(status));
- d335 15
- a349 16
- status = Fs_Write(streamID, UTIL_RECORD_SIZE, utilRecord,
- &bytesWritten);
- if (status != SUCCESS) {
- syslog(LOG_ERR, "%s: GetLoad: error in Fs_Write: %s\n", myName,
- Stat_GetMsg(status));
- Proc_Exit(status);
- }
- if (bytesWritten != UTIL_RECORD_SIZE) {
- syslog(LOG_ERR, "%s: GetLoad: only %d bytes written.\n",
- myName, bytesWritten);
- Proc_Exit(FAILURE);
- }
- /*
- * Need to read response from reply pipe here.
- */
- } else {
- d351 1
- a351 2
- Io_PrintStream(io_StdErr, "GetLoad: opening file %s.\n",
- dataFile);
- d354 1
- a354 1
- status = Fs_Open(dataFile, FS_READ, 0, &streamID);
- d356 2
- a357 2
- syslog(LOG_ERR, "%s: GetLoad: error opening data file: %s\n",
- myName, Stat_GetMsg(status));
- d360 2
- a361 18
- if (lockFile) {
- if (debug) {
- Io_PrintStream(io_StdErr, "GetLoad: calling Ioc_Lock.\n");
- Io_Flush(io_StdErr);
- }
- status = Ioc_Lock(streamID, IOC_LOCK_EXCLUSIVE);
- if (status != SUCCESS) {
- syslog(LOG_ERR, "%s: GetLoad: error in Ioc_Lock: %s\n",
- myName, Stat_GetMsg(status));
- Proc_Exit(status);
- }
- }
- maxSize = MAX_NUM_HOSTS * sizeof(NodeInfo);
- infoArray = (NodeInfo *) Mem_Alloc(maxSize);
- if (debug) {
- Io_PrintStream(io_StdErr, "GetLoad: calling Fs_Read.\n");
- Io_Flush(io_StdErr);
- }
- d363 8
- a370 10
- status = Fs_Read(streamID, maxSize, (Address) infoArray, &bytesRead);
- if (status != SUCCESS) {
- syslog(LOG_ERR, "%s: GetLoad: error in Fs_Read: %s\n", myName,
- Stat_GetMsg(status));
- Proc_Exit(status);
- }
- if (lockFile) {
- if (debug) {
- Io_PrintStream(io_StdErr, "GetLoad: calling Ioc_Unlock.\n");
- Io_Flush(io_StdErr);
- d372 4
- a375 5
- status = Ioc_Unlock(streamID, IOC_LOCK_EXCLUSIVE);
- if (status != SUCCESS) {
- Stat_PrintMsg(status,
- "GetLoad: error in Ioc_Unlock");
- Proc_Exit(status);
- d377 4
- a380 23
- }
- numRecs = bytesRead / sizeof(NodeInfo);
- lowestLoad = MAX_LOAD;
-
- for (i = 0; i < numRecs; i++) {
- infoPtr = &infoArray[i];
- if (infoPtr->timestamp != 0) {
- if (i != infoPtr->hostID) {
- Io_PrintStream(io_StdErr,
- "GetLoad: mismatch between counter (%d) and value in data file (%d).\n",
- i, infoPtr->hostID);
- Proc_Exit(FAILURE);
- }
- if (!getIdle && (allHosts || i == hostID)) {
- output = TRUE;
- } else {
- output = FALSE;
- }
- state = GetStatus(infoPtr, output);
- if (state == IDLE) {
- possibleHosts[numPossible] = i;
- numPossible += 1;
- }
- d383 15
- a397 14
- if (verbose) {
- Io_Flush(io_StdErr);
- }
- Mem_Free((Address) infoArray);
- if (!getIdle) {
- return;
- }
- if (debug) {
- Io_PrintStream(io_StdErr, "There are %d possible idle hosts.\n",
- numPossible);
- Io_Flush(io_StdErr);
- }
- if (numPossible > 0) {
- int randNum;
- d399 4
- a402 8
- Rand_InitSeed((unsigned) currentTime.microseconds);
- if (numPossible > 1) {
- randNum = Rand_GetValue();
- randNum = randNum % numPossible;
- } else {
- randNum = 0;
- }
- Io_Print("%d\n", possibleHosts[randNum]);
- d404 1
- a404 1
- Io_Print("0\n");
- d406 3
- @
-
-
- 2.7
- log
- @Changed to use syslog.
- @
- text
- @d14 1
- a14 1
- static char rcsid[] = "$Header: loadAvg.c,v 2.6 87/12/02 12:02:46 douglis Exp $ SPRITE (Berkeley)";
- d24 1
- d88 1
- d146 2
- d166 1
- d224 1
- a224 1
- if (! (runServer || runDaemon || getIdleNode || getLoad)) {
- d285 5
- d636 95
- @
-
-
- 2.6
- log
- @Print out uptime & idle time using Time_ToAscii. Fixed bug w/
- loadAvg/rup/... defaults. (Now rup implies getLoad & getAllHosts and
- anything else implies loadAvg of local host.)
-
- ToDo: allow host names, a la "rup" under unix.
- @
- text
- @d14 1
- a14 1
- static char rcsid[] = "$Header: loadAvg.c,v 2.5 87/12/01 20:52:50 douglis Exp $ SPRITE (Berkeley)";
- d23 1
- d101 2
- d199 2
- d211 1
- a211 1
- argv[0]);
- d220 1
- a220 1
- if (String_FindSubstring(argv[0], "rup") != NULL) {
- d230 1
- a230 1
- argv[0]);
- d265 2
- a266 1
- Stat_PrintMsg(status, "Error in Sys_GetMachineInfo");
- d271 2
- a272 1
- Stat_PrintMsg(status, "Error in Sys_GetTimeOfDay");
- d360 2
- a361 1
- Stat_PrintMsg(status, "GetLoad: error in Fs_Open");
- d367 2
- a368 1
- Stat_PrintMsg(status, "GetLoad: error in Fs_Write");
- d372 2
- a373 2
- Io_PrintStream(io_StdErr, "GetLoad: only %d bytes written.\n",
- bytesWritten);
- d387 2
- a388 1
- Stat_PrintMsg(status, "GetLoad: error opening data file");
- d398 2
- a399 1
- Stat_PrintMsg(status, "GetLoad: error in Ioc_Lock");
- d412 2
- a413 1
- Stat_PrintMsg(status, "GetLoad: error in Fs_Read");
- d521 2
- a522 1
- Stat_PrintMsg(status, "Sys_GetHostnameByID");
- d537 1
- a537 1
- "%18s%1s %s %s %s",
- @
-
-
- 2.5
- log
- @Changed to stop complaining if the update time is later than our idea
- of the current time.
- @
- text
- @d14 1
- a14 1
- static char rcsid[] = "$Header: loadAvg.c,v 2.4 87/11/20 12:40:01 douglis Exp $ SPRITE (Berkeley)";
- d214 2
- a215 2
- if (! (runServer || runDaemon || getIdleNode)) {
- if (String_FindSubstring(argv[0], "loadAvg") != NULL) {
- a216 2
- } else if (String_FindSubstring(argv[0], "rup") != NULL) {
- getLoad = TRUE;
- d219 1
- a219 2
- Opt_PrintUsage(argv[0], numOptions, optionArray);
- Proc_Exit(FAILURE);
- d489 3
- d499 1
- d524 1
- a524 1
- "%20s%1s %s",
- d526 1
- d529 1
- d531 1
- a531 1
- " %5.2lf %5.2lf %5.2lf (%d)",
- d533 1
- a533 1
- infoPtr->lengths[2], infoPtr->noInput);
- a539 5
- #define UP_STR_LEN 64
- #define SECS_PER_MIN 60
- #define MINS_PER_HOUR 60
- #define HOURS_PER_DAY 24
-
- d546 1
- a546 5
- static char str[UP_STR_LEN];
- Boolean up = TRUE;
- int minutes;
- int hours;
- int days;
- a556 1
- up = FALSE;
- a566 1
- Io_PrintString(str, "???? ??:??");
- d568 1
- a568 1
- return(str);
- a571 5
- minutes = (diff + SECS_PER_MIN - 1) / SECS_PER_MIN;
- hours = minutes / MINS_PER_HOUR;
- minutes = minutes % MINS_PER_HOUR;
- days = hours / HOURS_PER_DAY;
- hours = hours % HOURS_PER_DAY;
- d573 3
- a575 4
- Io_PrintString(str, "%4s %3d+%02d:%02d",
- up ? "up" : "down",
- days, hours, minutes);
- return(str);
- @
-
-
- 2.4
- log
- @Made it emulate "ruptime", use host names instead of numbers for load avg.
- @
- text
- @d14 1
- a14 1
- static char rcsid[] = "$Header: loadAvg.c,v 2.3 87/11/19 19:52:47 douglis Exp $ SPRITE (Berkeley)";
- d556 5
- a561 15
- if (diff < 0) {
- /*
- * If just a little off, assume clock skew and permit the entry.
- */
- if (diff >= -10) {
- diff = 0;
- } else {
- Io_PrintStream(io_StdErr,
- "Entry updated before current time: currentTime %d, modTime %d.\n",
- currentTime.seconds, modTime);
- Io_PrintString(str, "???? ??:??");
- *statePtr = DOWN;
- return(str);
- }
- }
- d566 3
- @
-
-
- 2.3
- log
- @decreased WRITE_INTERVAL. Moved to /sprite/spool/loadAvg. Changed
- around some options. Changed to allow getting load avg of current
- node, all nodes. Fixed bug with closing file w/o unlocking it,
- not keeping valid offset value.
- @
- text
- @d6 2
- a7 1
- * or as a stand-alone program (to return the load of the local host).
- d14 1
- a14 1
- static char rcsid[] = "$Header: loadAvg.c,v 2.1 87/03/11 18:12:13 douglis Exp $ SPRITE (Berkeley)";
- d22 1
- d72 1
- d101 2
- d104 1
- a104 1
- "Get the load average of this node (DEFAULT)."},
- d144 10
- d155 1
- d157 1
- d159 2
- d162 1
- d215 9
- a223 1
- getLoad = TRUE;
- d258 4
- a261 1
- status = Sys_GetMachineInfo(NULL, NULL, &hostID);
- d266 5
- d283 1
- a283 1
- GetLoad(FALSE);
- d286 1
- a286 1
- GetLoad(TRUE);
- d298 2
- a299 2
- * Output the load average of this node or of an idle node. If getting
- * idle node and not verbose, just output hostID.
- d314 2
- a315 2
- GetLoad(thisHost)
- Boolean thisHost; /* if TRUE, just look up this host */
- d333 2
- a334 1
- Time currentTime;
- d344 1
- a344 1
- if (thisHost) {
- d381 1
- a381 1
- Stat_PrintMsg(status, "GetLoad: error in Fs_Open");
- a420 1
- Sys_GetTimeOfDay(¤tTime, NULL, NULL);
- d425 3
- a427 4
- if (currentTime.seconds - infoPtr->timestamp <= timeOut) {
- if (i != infoPtr->hostID) {
- Io_PrintStream(io_StdErr,
- "GetLoad: mismatch between counter (%d) and value in data file (%d).\n",
- d429 1
- a429 18
- Proc_Exit(FAILURE);
- }
- if (verbose || (thisHost && i == hostID)) {
- Io_PrintStream(io_StdErr,
- "Node %d\tTime %d\tload average %5.2lf %5.2lf %5.2lf\tidle %d\t Allow = %d.\n",
- infoPtr->hostID, infoPtr->timestamp,
- infoPtr->lengths[0], infoPtr->lengths[1],
- infoPtr->lengths[2], infoPtr->noInput,
- infoPtr->allowMigration);
- }
-
- if (infoPtr->allowMigration) {
- possibleHosts[numPossible] = i;
- numPossible += 1;
- }
- } else if (debug || verbose || (thisHost && i == hostID)) {
- Io_PrintStream(io_StdErr, "Node %d has old information: current time %d, time updated %d.\n",
- i, currentTime.seconds, infoPtr->timestamp);
- d431 10
- d447 1
- a447 1
- if (thisHost) {
- d472 126
- @
-
-
- 2.2
- log
- @Combined thresholds into a single structure. Added getting random node.
- @
- text
- @d18 1
- d34 1
- a34 1
- #define WRITE_INTERVAL (60 * LOAD_INTERVAL)
- d70 1
- d83 1
- a83 1
- char *pipeDir = "/etc/daemons";
- d86 1
- a86 1
- char *dataFile = "/etc/utilization";
- d98 4
- a101 2
- {OPT_TRUE, 'g', (Address)&getIdleNode,
- "Get the hostID of an idle node (DEFAULT)."},
- d109 1
- a109 1
- {OPT_INT, 'l', (Address)&loadInterval,
- d117 1
- a117 1
- "Output options:\n\tUse shared data file for global load information."},
- d123 1
- a123 1
- "File name to write data (default \"/etc/utilization\")."},
- d125 1
- a125 1
- "Directory containing named pipes (default \"/etc/daemons\")."},
- d127 1
- a127 1
- "Request named pipe name (default \"globalLoad.request\")."},
- d129 3
- a131 3
- "Response pipe name (default \"globalLoad.response\")."},
- {OPT_INT, 'i', (Address)&thresholds.noInput,
- "Minimum idle time to allow foreign procs (default 30s)."},
- d133 1
- a133 1
- "Maximum load average to allow foreign procs (default 0.3)."},
- d141 1
- a141 1
- static void GetIdleNode();
- d191 1
- a191 1
- * Default operation is to get an idle node, using a global data file.
- d195 1
- a195 4
- getIdleNode = TRUE;
- if (! usePipes) {
- useDataFile = TRUE;
- }
- d236 4
- d247 1
- a247 1
- GetIdleNode();
- d249 3
- d260 1
- a260 1
- * GetIdleNode --
- d262 2
- a263 1
- * Output the hostID of an idle node.
- d269 1
- a269 1
- * The ID is written to io_StdOut.
- d271 3
- d278 2
- a279 1
- GetIdleNode()
- d302 1
- a302 1
- Io_PrintStream(io_StdErr, "GetIdleNode called.\n");
- d307 3
- d313 1
- a313 1
- Io_PrintStream(io_StdErr, "GetIdleNode: opening file %s.\n", fileName);
- d319 1
- a319 1
- Stat_PrintMsg(status, "GetIdleNode: error in Fs_Open");
- d325 1
- a325 1
- Stat_PrintMsg(status, "GetIdleNode: error in Fs_Write");
- d329 1
- a329 1
- Io_PrintStream(io_StdErr, "GetIdleNode: only %d bytes written.\n",
- d338 1
- a338 1
- Io_PrintStream(io_StdErr, "GetIdleNode: opening file %s.\n",
- d344 1
- a344 1
- Stat_PrintMsg(status, "GetIdleNode: error in Fs_Open");
- d349 1
- a349 1
- Io_PrintStream(io_StdErr, "GetIdleNode: calling Fs_Lock.\n");
- d352 1
- a352 1
- status = Fs_Lock(streamID, FS_LOCK_EXCLUSIVE);
- d354 1
- a354 1
- Stat_PrintMsg(status, "GetIdleNode: error in Fs_Lock");
- d361 1
- a361 1
- Io_PrintStream(io_StdErr, "GetIdleNode: calling Fs_Read.\n");
- d367 1
- a367 1
- Stat_PrintMsg(status, "GetIdleNode: error in Fs_Read");
- d372 1
- a372 1
- Io_PrintStream(io_StdErr, "GetIdleNode: calling Fs_(Un)Lock.\n");
- d375 1
- a375 1
- status = Fs_Lock(streamID, FS_LOCK_EXCLUSIVE | FS_UNLOCK);
- d378 1
- a378 1
- "GetIdleNode: error in Fs_Lock while unlocking file");
- d388 24
- a411 7
- if (infoPtr->timestamp != 0 &&
- (currentTime.seconds - infoPtr->timestamp <= timeOut)) {
- if (i != infoPtr->hostID) {
- Io_PrintStream(io_StdErr,
- "GetIdleNode: mismatch between counter (%d) and value in data file (%d).\n",
- i, infoPtr->hostID);
- Proc_Exit(FAILURE);
- a412 13
- if (verbose) {
- Io_PrintStream(io_StdErr,
- "Node %d\tTime %d\tload average %5.2lf %5.2lf %5.2lf\tidle %d\t Allow = %d.\n",
- infoPtr->hostID, infoPtr->timestamp,
- infoPtr->lengths[0], infoPtr->lengths[1],
- infoPtr->lengths[2], infoPtr->noInput,
- infoPtr->allowMigration);
- }
-
- if (infoPtr->allowMigration) {
- possibleHosts[numPossible] = i;
- numPossible += 1;
- }
- d419 3
- d429 2
- a430 1
-
- d438 2
- @
-
-
- 2.1
- log
- @Keep track of whether to migrate processes based on load average
- and keyboard/mouse idle time.
- @
- text
- @d13 1
- a13 1
- static char rcsid[] = "$Header: loadAvg.c,v 2.0 87/03/11 12:39:41 douglis Exp $ SPRITE (Berkeley)";
- d19 1
- d22 31
- a52 4
- * Define arbitrary limits. Accept migrated processes if the load average
- * is below THRESHOLD_LOW and stop accepting them if it goes over
- * THRESHOLD_HIGH. INPUT_THRESHOLD is the number of seconds that a node must
- * be idle for it to accept migrated processes. (Set to 60 seconds for
- d58 4
- a61 2
- #define THRESHOLD_HIGH 0.8
- #define INPUT_THRESHOLD 60
- d63 6
- d72 1
- d75 1
- d85 8
- a92 4
- char *weightString = NULL;
- double weights[] = {WEIGHT1, WEIGHT2, WEIGHT3};
- int inputThreshold = INPUT_THRESHOLD;
- double queueThreshold[] = {THRESHOLD_LOW, THRESHOLD_HIGH};
- d103 8
- a110 4
- {OPT_INT, 'i', (Address)&loadInterval,
- "Interval between iterations for getting load info (default 5 seconds)"},
- {OPT_INT, 'I', (Address)&writeInterval,
- "Interval between outputting load info (default 5 seconds)"},
- d116 1
- a116 1
- {OPT_TRUE, 'L', (Address)&lockFile,
- d126 4
- d131 1
- a131 3
- "Specify two limits for migration (as in the form '-T \"0.3 0.8\"')."},
- {OPT_STRING, 'W', (Address)&weightString,
- "Specify three weights for exponential averaging (as in the form '-W \".2 .5 .9\"')."},
- d164 1
- d203 3
- a205 7
- if (weightString) {
- numScanned = Io_ScanString(weightString, "%f %f %f",
- &weights[0], &weights[1], &weights[2]);
- if (numScanned < 3) {
- Io_PrintStream(io_StdErr, "%s: Invalid weights '%s'.\n",
- weightString);
- Proc_Exit(FAILURE);
- d208 1
- a208 1
-
- d210 4
- a213 3
- numScanned = Io_ScanString(thresholdString, "%lf %lf",
- &queueThreshold[0], &queueThreshold[1]);
- if (numScanned < 2) {
- d278 2
- a279 1
- NodeInfo *infoPtr;
- d284 3
- d297 1
- a297 1
- Io_PrintStream(io_StdErr, "Opening file %s.\n", fileName);
- d303 1
- a303 1
- Stat_PrintMsg(status, "Error in Fs_Open");
- d309 1
- a309 1
- Stat_PrintMsg(status, "Error in Fs_Write");
- d313 1
- a313 1
- Io_PrintStream(io_StdErr, "Only %d bytes written.\n",
- d322 2
- a323 1
- Io_PrintStream(io_StdErr, "Opening file %s.\n", dataFile);
- d328 1
- a328 1
- Stat_PrintMsg(status, "Error in Fs_Open");
- d332 4
- d338 1
- a338 1
- Stat_PrintMsg(status, "Error in Fs_Lock");
- d343 7
- a349 2
- infoPtr = (NodeInfo *) Mem_Alloc(maxSize);
- status = Fs_Read(streamID, maxSize, (Address) infoPtr, &bytesRead);
- d351 1
- a351 1
- Stat_PrintMsg(status, "Error in Fs_Read");
- d355 4
- d361 2
- a362 1
- Stat_PrintMsg(status, "Error in Fs_Lock while unlocking file");
- d368 2
- d371 4
- a374 2
- if (infoPtr[i].timestamp != 0) {
- if (i != infoPtr[i].hostID) {
- d376 2
- a377 2
- "Mismatch between counter (%d) and value in data file (%d).\n",
- i, infoPtr[i].hostID);
- d380 13
- a392 9
- Io_Print(
- "Node %d\tTime %d\tload average %5.2lf %5.2lf %5.2lf\tidle %d\t Allow = %d.\n",
- infoPtr[i].hostID, infoPtr[i].timestamp,
- infoPtr[i].lengths[0], infoPtr[i].lengths[1],
- infoPtr[i].lengths[2], infoPtr[i].noInput,
- infoPtr[i].allowMigration);
- /*
- * Should retain info for lowest avg node.
- */
- d395 20
- a414 1
- Mem_Free((Address) infoPtr);
- @
-
-
- 2.0
- log
- @Split into header file & separate modules (daemon, server, &
- loadAvg (main)).
- @
- text
- @d13 1
- a13 1
- static char rcsid[] = "$Header: loadAvg.c,v 1.8 87/03/11 11:09:50 douglis Exp $ SPRITE (Berkeley)";
- d20 13
- a39 1
- Boolean writeToStdOut = FALSE;
- d42 1
- a42 1
- Boolean lockFile = FALSE;
- d49 3
- a69 2
- {OPT_TRUE, 'S', (Address)&writeToStdOut,
- "\tOutput daemon's info to standard output (for debugging)."},
- d71 1
- a71 1
- "Lock data file during use (not valid with -p or -s options)."},
- d80 2
- d83 1
- a83 1
- "Specify three weights for exponential averaging (as in the form '-w \".2 .5 .9\"')."},
- d128 1
- a128 1
- if (! (useDataFile || usePipes || writeToStdOut)) {
- d164 10
- d232 1
- d239 2
- a240 1
- Io_Print("GetIdleNode called.\n");
- d287 3
- a289 3
- maxSize = MAX_NUM_HOSTS * UTIL_RECORD_SIZE;
- utilsPtr = Mem_Alloc(maxSize);
- status = Fs_Read(streamID, maxSize, utilsPtr, &bytesRead);
- d301 1
- a301 1
- numRecs = bytesRead / UTIL_RECORD_SIZE;
- d303 3
- a305 15
- for (i = 0, utilPtr = utilsPtr; i < numRecs;
- i++, utilPtr += UTIL_RECORD_SIZE) {
- if (*utilPtr != '\0') {
- numScanned = Io_ScanString(utilPtr,
- "%*d %d %d %d %d %d %d %lf %lf %lf",
- &hostID,
- &nodeInfo.timestamp,
- &nodeInfo.noInput,
- &nodeInfo.utils[0],
- &nodeInfo.utils[1],
- &nodeInfo.utils[2],
- &nodeInfo.lengths[0],
- &nodeInfo.lengths[1],
- &nodeInfo.lengths[2]);
- if (numScanned != 9) {
- a306 8
- "Error scanning data for node %d. Scanned only %d items.\n",
- i, numScanned);
- #ifdef notdef
- Proc_Exit(FAILURE);
- #endif
- }
- if (i != hostID) {
- Io_PrintStream(io_StdErr,
- d308 1
- a308 1
- i, hostID);
- d311 6
- a316 2
- Io_Print("Node %d\tload average %5.2lf\tidle %d.\n", hostID,
- nodeInfo.lengths[2], nodeInfo.noInput);
- d322 1
- a322 1
- Mem_Free(utilsPtr);
- d346 1
- a346 1
- static ReturnStatus
- @
-
-
- 1.8
- log
- @Changed file opens to use CREATE flag only if file is not found.
- Keep track of time since last keyboard/mouse input.
- @
- text
- @d13 1
- a13 1
- static char rcsid[] = "$Header: loadAvg.c,v 1.7 87/03/09 12:14:30 douglis Exp $ SPRITE (Berkeley)";
- d17 1
- a17 8
- #include "sprite.h"
- #include "fs.h"
- #include "sync.h"
- #include "status.h"
- #include "io.h"
- #include "proc.h"
- #include "rpc.h"
- #include "kernel/sched.h"
- a18 3
- #include "ioc.h"
- #include "byte.h"
- #include "mem.h"
- a19 39
- /*
- * Define pseudo-RPC protocol for named pipes.
- *
- * LA_RPC_UPDATE - update load statistics for a node
- * LA_RPC_IDLE - get an idle node
- * LA_RPC_ALLINFO - output statistics for all nodes
- */
-
- #define LA_RPC_UPDATE 0
- #define LA_RPC_IDLE 1
- #define LA_RPC_ALL_INFO 2
-
- /*
- * Define constants specific to load average statistics.
- */
-
- #define LOAD_INTERVAL 5
- #define WRITE_INTERVAL (1 * LOAD_INTERVAL)
- #define WEIGHT1 (double) 0.9200444146293232 /* exp(-1/12) */
- #define WEIGHT2 (double) 0.9834714538216174 /* exp(-1/60) */
- #define WEIGHT3 (double) 0.9944598480048967 /* exp(-1/180) */
- #define LOAD_NUM_VALUES 3
-
- /*
- * Define constants related to Sprite system characteristics and defaults.
- */
-
- #define STANDARD_OUTPUT 1
- #define OPEN_MODE 0664
- #define MAX_NUM_HOSTS 256
-
- /*
- * A record contains "%2d %3d %10d %10d %3.0f %3.0f %3.0f %5.2f %5.2f %5.2f\n",
- * plus a null byte. (This amounts to 54 bytes.) Make it the next
- * power of 2.
- */
-
- #define UTIL_RECORD_SIZE 64
-
- d70 1
- a70 1
- int numOptions = sizeof(optionArray) / sizeof(Option);
- d72 1
- a72 4
- /*
- * Information maintained by the local daemon, containing scheduler statistics
- * at some instant in time.
- */
- d74 1
- a74 5
- typedef struct {
- int lowTicks;
- int highTicks;
- int queueLength;
- } Stats;
- a75 38
- /*
- * Keep track of both utilization and ready-queue length when load
- * averages are used.
- */
-
- typedef struct {
- double utilization;
- double queueLength;
- } Load;
-
- /*
- * For each machine, keep track of the timestamp for its information and the
- * different load averages reported. (Used only by the server.)
- */
-
- typedef struct {
- int utils[LOAD_NUM_VALUES];
- double lengths[LOAD_NUM_VALUES];
- int timestamp;
- int noInput;
- } NodeInfo;
-
- #define HIGH_TO_LOW_TICKS ((unsigned)0xffffffff)
- #define AND3(a, b, c) (((a) && (b)) || ((a) && (c)) || ((b) && (c)))
-
- void RunDaemon();
- void RunServer();
- void GetStats();
- void PrintAllInfo();
- void OutputLoads();
- void CalculateLoads();
- void GetIdleNode();
- void UpdateData();
- static ReturnStatus OpenCreate();
-
- static unsigned int maxIdle;
- int hostID;
-
- a180 549
- * RunDaemon --
- *
- * (Optionally) fork a child to be the local daemon. This daemon will
- * periodically send load information to a global server using named
- * pipes.
- *
- * Results:
- * None.
- *
- * Side effects:
- * A second process may be created.
- *
- *----------------------------------------------------------------------
- */
-
- void
- RunDaemon()
- {
- ReturnStatus status;
- Time sleepTime;
- Time time;
- Load loads[LOAD_NUM_VALUES];
- Proc_PID pid;
- int streamID;
- char *fileName;
- char fileNameBuffer[FS_MAX_PATH_NAME_LENGTH];
- int flags = FS_WRITE;
- int mode = OPEN_MODE;
- Stats stats[2];
- int nextStat;
- int iterationNumber;
- int writeRate;
- int noInput;
-
-
- if (forkChild) {
- status = Proc_Fork(FALSE, &pid);
- } else {
- status = PROC_CHILD_PROC;
- }
- if (status == PROC_CHILD_PROC) {
- sleepTime.seconds = loadInterval;
- sleepTime.microseconds = 0;
-
- if (useDataFile || usePipes) {
- if (useDataFile) {
- fileName = dataFile;
- } else {
- fileName = fileNameBuffer;
- Io_PrintString(fileName, "%s/%s", pipeDir, requestFile);
- flags |= FS_NAMED_PIPE_OPEN;
- }
- if (debug) {
- Io_PrintStream(io_StdErr, "Opening file %s.\n", fileName);
- Io_Flush(io_StdErr);
- }
- status = OpenCreate(fileName, flags, mode, &streamID);
- if (status != SUCCESS) {
- Stat_PrintMsg(status, "Error in Fs_Open");
- Proc_Exit(status);
- }
- } else {
- streamID = STANDARD_OUTPUT;
- }
-
- /*
- * Get the initial load value.
- */
-
- GetStats(&stats[0], (Time *) NULL, &noInput);
- status = Sync_WaitTime(sleepTime);
- if (status != SUCCESS) {
- Proc_Exit(status);
- }
- nextStat = 1;
- iterationNumber = 0;
- writeRate = writeInterval / loadInterval;
-
- while(TRUE) {
- GetStats(&stats[nextStat], &time, &noInput);
- nextStat = (nextStat + 1) % 2;
- CalculateLoads(stats, nextStat, loads);
- if (iterationNumber == 0) {
- OutputLoads(streamID, loads, time);
- }
- iterationNumber = (iterationNumber + 1) % writeRate;
- status = Sync_WaitTime(sleepTime);
- if (status != SUCCESS) {
- Proc_Exit(status);
- }
- }
- } else if (status != SUCCESS) {
- Stat_PrintMsg(status, "Error in Proc_Fork");
- Proc_Exit(status);
- }
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * CalculateLoads --
- *
- * Given the number of idle ticks at two different times, calculate
- * the utilization of the computer during that period of time and
- * average with weighted values of utilization over different times.
- *
- * The same calculation is performed for ready queue length.
- *
- * Results:
- * The calculated utilization & average queue lengths are returned in
- * loads[0..LOAD_NUM_VALUES].
- *
- * Side effects:
- * None.
- *
- *----------------------------------------------------------------------
- */
-
- void
- CalculateLoads(stats, nextStat, loads)
- Stats stats[];
- int nextStat;
- Load loads[];
- {
- double currentLoad;
- register Stats *oldStatsPtr;
- register Stats *newStatsPtr;
- unsigned lowTicks;
- int i;
- static Boolean init = FALSE;
-
- if (nextStat == 0) {
- oldStatsPtr = stats;
- newStatsPtr = &(stats[1]);
- } else {
- newStatsPtr = stats;
- oldStatsPtr = &(stats[1]);
- }
- if (newStatsPtr->highTicks != oldStatsPtr->highTicks) {
- lowTicks = HIGH_TO_LOW_TICKS - oldStatsPtr->lowTicks +
- newStatsPtr->lowTicks;
- } else {
- lowTicks = newStatsPtr->lowTicks - oldStatsPtr->lowTicks;
- }
-
- #define DEBUG
- #ifdef DEBUG
- if (debug) {
- Io_PrintStream(io_StdErr, "Lowticks=%d.\n", lowTicks);
- }
- #endif
- /*
- * Since we don't get an absolute record of the time, it is possible
- * to sleep a little too long and wind up with lowTicks > maxIdle.
- */
-
- if (lowTicks > maxIdle) {
- currentLoad = 0.;
- } else {
- currentLoad = 1 - ((double)lowTicks)/maxIdle;
- }
-
- if (debug) {
- #ifdef DEBUG
- Io_PrintStream(io_StdErr,
- "OldStatsPtr->lowTicks=%d, newStatsPtr->lowTicks=%d.\n",
- oldStatsPtr->lowTicks, newStatsPtr->lowTicks);
- #endif
- Io_PrintStream(io_StdErr,
- "Idle ticks %d/%d => %6.2f%% Utilization, Queue length %d.\n",
- lowTicks,
- maxIdle,
- currentLoad * 100,
- newStatsPtr->queueLength);
- Io_Flush(io_StdErr);
- }
-
- if (!init) {
- init = TRUE;
- for (i = 0; i < LOAD_NUM_VALUES; i++) {
- loads[i].utilization = currentLoad;
- loads[i].queueLength = newStatsPtr->queueLength;
- }
- } else {
- for (i = 0; i < LOAD_NUM_VALUES; i++) {
- loads[i].utilization = weights[i] * loads[i].utilization +
- (1 - weights[i]) * currentLoad;
- loads[i].queueLength = weights[i] * loads[i].queueLength +
- (1 - weights[i]) * newStatsPtr->queueLength;
- }
- }
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * GetStats --
- *
- * Get the current number of idle ticks and the length of the
- * ready queue.
- *
- * Results:
- * The number of ticks and length of the ready queue are
- * returned in *statsPtr. The current time and time since last user
- * input are also returned.
- *
- * Side effects:
- * The global variable 'maxIdle' is initialized to
- * idleTicksPerSecond * LOAD_INTERVAL.
- *
- *----------------------------------------------------------------------
- */
-
- void
- GetStats(statsPtr, timePtr, noInputPtr)
- Stats *statsPtr;
- Time *timePtr;
- int *noInputPtr;
- {
- Sched_Instrument stats;
- static Boolean init = FALSE;
-
- Test_Stats(SCHED_STATS, 0, &stats);
- statsPtr->lowTicks = stats.idleTicksLow;
- statsPtr->highTicks = stats.idleTicksOverflow;
- statsPtr->queueLength = stats.numReadyProcesses;
- *noInputPtr = stats.noUserInput.seconds;
-
- if (timePtr != NULL) {
- Sys_GetTimeOfDay(timePtr, NULL, NULL);
- }
- if (!init) {
- maxIdle = stats.idleTicksPerSecond * LOAD_INTERVAL;
- init = TRUE;
- }
-
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * OutputLoads --
- *
- * Write the most recent utilization information to a file or to the
- * standard output. If writing to a file, reposition to write the
- * data in the record corresponding to the ID of the current host.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Data is output to a file (or to the standard output).
- *
- *----------------------------------------------------------------------
- */
-
- void
- OutputLoads(streamID, loads, time, noInput)
- int streamID;
- Load loads[];
- Time time;
- int noInput;
- {
- static IOC_RepositionArgs args;
- static init = FALSE;
- int oldOffset; /* ignored */
- static char utilRecord[UTIL_RECORD_SIZE];
- int bytesWritten;
- ReturnStatus status;
-
- if (!init) {
- init = TRUE;
- args.base = IOC_BASE_ZERO;
- args.offset = hostID * UTIL_RECORD_SIZE;
- Byte_Zero(UTIL_RECORD_SIZE, utilRecord);
- }
- #ifdef notdef
- if (debug) {
- Io_PrintStream(io_StdErr, "OutputLoads: streamID = %d.\n", streamID);
- Io_Flush(io_StdErr);
- }
- #endif
-
- Io_PrintString(utilRecord,
- "%2d %3d %10u %10u %3.0f %3.0f %3.0f %5.2f %5.2f %5.2f\n",
- LA_RPC_UPDATE, hostID, time.seconds, noInput,
- loads[0].utilization * 100, loads[1].utilization * 100,
- loads[2].utilization * 100,
- loads[0].queueLength, loads[1].queueLength,
- loads[2].queueLength);
-
- if (lockFile) {
- status = Fs_Lock(streamID, FS_LOCK_EXCLUSIVE);
- if (status != SUCCESS) {
- Stat_PrintMsg(status, "Error in Fs_Lock");
- Proc_Exit(status);
- }
- }
- if (useDataFile) {
- status = IOC_Reposition(streamID, &args, &oldOffset);
- if (status != SUCCESS) {
- Stat_PrintMsg(status, "Error in IOC_Reposition");
- Proc_Exit(status);
- }
- }
- status = Fs_Write(streamID, UTIL_RECORD_SIZE, utilRecord,
- &bytesWritten);
- if (status != SUCCESS) {
- Stat_PrintMsg(status, "Error in Fs_Read");
- Proc_Exit(status);
- }
- if (bytesWritten != UTIL_RECORD_SIZE) {
- Io_PrintStream(io_StdErr, "Only %d bytes written.\n", bytesWritten);
- Proc_Exit(FAILURE);
- }
- if (lockFile) {
- status = Fs_Lock(streamID, FS_LOCK_EXCLUSIVE | FS_UNLOCK);
- if (status != SUCCESS) {
- Stat_PrintMsg(status, "Error in Fs_Lock while unlocking file");
- Proc_Exit(status);
- }
- }
- }
-
-
-
- /*
- *----------------------------------------------------------------------
- *
- * RunServer --
- *
- * (Optionally) fork a child to be the global server. This daemon will
- * receive load information from local daemons using named
- * pipes and respond to requests for lighty-loaded machines.
- *
- * Results:
- * None.
- *
- * Side effects:
- * A second process may be created.
- *
- *----------------------------------------------------------------------
- */
-
- void
- RunServer()
- {
- ReturnStatus status;
- NodeInfo nodeInfo[MAX_NUM_HOSTS];
- Proc_PID pid;
- int requestStreamID;
- int responseStreamID;
- char fileName[FS_MAX_PATH_NAME_LENGTH];
- int i;
- int bytesRead;
- char buffer[UTIL_RECORD_SIZE];
- char *bufPtr;
- int numScanned;
- int flags;
- int requestType;
-
-
- if (forkChild) {
- status = Proc_Fork(FALSE, &pid);
- } else {
- status = PROC_CHILD_PROC;
- }
- if (status == PROC_CHILD_PROC) {
- Io_PrintString(fileName, "%s/%s", pipeDir, requestFile);
- flags = FS_READ | FS_NAMED_PIPE_OPEN;
- if (debug) {
- Io_PrintStream(io_StdErr, "Opening file %s.\n", fileName);
- Io_Flush(io_StdErr);
- }
- status = Fs_Open(fileName, flags, 0, &requestStreamID);
- if (status != SUCCESS) {
- Stat_PrintMsg(status, "Error in Fs_Open");
- Proc_Exit(status);
- }
-
- Io_PrintString(fileName, "%s/%s", pipeDir, responseFile);
- flags = FS_WRITE | FS_CREATE | FS_NAMED_PIPE_OPEN;
- if (debug) {
- Io_PrintStream(io_StdErr, "Opening file %s.\n", fileName);
- Io_Flush(io_StdErr);
- }
- status = Fs_Open(fileName, flags, OPEN_MODE, &responseStreamID);
- if (status != SUCCESS) {
- Stat_PrintMsg(status, "Error in Fs_Open");
- Proc_Exit(status);
- }
-
- for (i = 0; i < MAX_NUM_HOSTS; i++) {
- nodeInfo[i].timestamp = NIL;
- }
-
- while(TRUE) {
- status = Fs_Read(requestStreamID, UTIL_RECORD_SIZE, buffer,
- &bytesRead);
- if (status != SUCCESS) {
- Stat_PrintMsg(status, "Error in Fs_Read");
- Proc_Exit(status);
- }
- if (bytesRead != UTIL_RECORD_SIZE) {
- Io_PrintStream(io_StdErr, "Only %d bytes read.\n",
- bytesRead);
- Proc_Exit(FAILURE);
- }
- bufPtr = buffer;
- numScanned = Io_ScanString(bufPtr, "%2d", &requestType);
- if (numScanned != 1) {
- Io_PrintStream(io_StdErr,
- "Error scanning request type from pipe. Input string is '%s'.\n",
- bufPtr);
- Proc_Exit(FAILURE);
- }
- bufPtr += 3;
- switch (requestType) {
- case LA_RPC_UPDATE: {
- UpdateData(bufPtr, nodeInfo);
- break;
- }
- case LA_RPC_IDLE: {
- #ifdef notdone
- PrintIdleNode(nodeInfo);
- #else
- PrintAllInfo(nodeInfo);
- #endif
- break;
- }
- case LA_RPC_ALL_INFO: {
- PrintAllInfo(nodeInfo);
- break;
- }
- }
- }
- } else if (status != SUCCESS) {
- Stat_PrintMsg(status, "Error in Proc_Fork");
- Proc_Exit(status);
- }
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * UpdateData --
- *
- * Update the information for a node.
- *
- * Results:
- * None.
- *
- * Side effects:
- * 'nodeInfo' is updated for the specified host.
- *
- *----------------------------------------------------------------------
- */
-
- void
- UpdateData(bufPtr, nodeInfo)
- char *bufPtr; /* buffer containing data to be parsed */
- NodeInfo nodeInfo[]; /* pointer to array of per-node data */
- {
- int numScanned;
- int hostID;
- NodeInfo info;
-
- numScanned = Io_ScanString(bufPtr,
- "%d %d %d %d %d %d %lf %lf %lf",
- &hostID,
- &info.timestamp,
- &info.noInput,
- &info.utils[0],
- &info.utils[1],
- &info.utils[2],
- &info.lengths[0],
- &info.lengths[1],
- &info.lengths[2]);
- if (numScanned != 9) {
- Io_PrintStream(io_StdErr,
- "Error scanning information from request pipe. Scanned %d items.\n",
- numScanned);
- Proc_Exit(FAILURE);
- }
- if (hostID <= 0 || hostID >= MAX_NUM_HOSTS) {
- Io_PrintStream(io_StdErr, "Invalid hostID: %d.\n", hostID);
- Proc_Exit(FAILURE);
- }
- if (debug) {
- Io_PrintStream(io_StdErr,
- "Received info from node %d.\n", hostID);
- Io_Flush(io_StdErr);
- }
- nodeInfo[hostID] = info;
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- * PrintAllInfo --
- *
- * Print statistics for all nodes.
- *
- * Results:
- * None.
- *
- * Side effects:
- * Data is written to io_StdOut.
- *
- *----------------------------------------------------------------------
- */
-
- void
- PrintAllInfo(nodeInfo)
- NodeInfo nodeInfo[]; /* array of per-node data */
- {
- int hostID;
-
- if (debug) {
- Io_PrintStream(io_StdErr,
- "Received request for idle node.\n");
- }
- for (hostID = 0; hostID < MAX_NUM_HOSTS; hostID++) {
- if (nodeInfo[hostID].timestamp != NIL) {
- Io_PrintStream(io_StdErr,
- "%3d %10u %10u %3d %3d %3d %5.2lf %5.2lf %5.2lf\n",
- hostID,
- nodeInfo[hostID].timestamp,
- nodeInfo[hostID].noInput,
- nodeInfo[hostID].utils[0],
- nodeInfo[hostID].utils[1],
- nodeInfo[hostID].utils[2],
- nodeInfo[hostID].lengths[0],
- nodeInfo[hostID].lengths[1],
- nodeInfo[hostID].lengths[2]);
- }
- }
- Io_Flush(io_StdErr);
- }
-
-
- /*
- *----------------------------------------------------------------------
- *
- d194 1
- a194 6
- /*
- * Arbitrary value larger than the load average on any node
- */
- #define MAX_LOAD 1000.0
-
- void
- a351 2
-
-
- @
-
-
- 1.7
- log
- @successfully prints out list of load averages for shared file case.
- @
- text
- @d13 1
- a13 1
- static char rcsid[] = "$Header: loadAvg.c,v 1.6 87/03/03 14:57:39 douglis Exp $ SPRITE (Berkeley)";
- a57 1
- #define OPEN_WRITE_FLAGS (FS_WRITE | FS_CREATE)
- d62 2
- a63 2
- * A record contains "%2d %3d %10d %3.0f %3.0f %3.0f %5.2f %5.2f %5.2f\n",
- * plus a null byte. (This amounts to 43 bytes.) Make it the next
- d148 4
- a151 3
- int utils[LOAD_NUM_VALUES];
- double lengths[LOAD_NUM_VALUES];
- int timestamp;
- a155 2
- void RunDaemon(), RunServer(), GetStats(), PrintAllInfo(),
- OutputLoads(), CalculateLoads(), GetIdleNode(), UpdateData();
- d157 10
- d301 1
- a301 1
- int flags = OPEN_WRITE_FLAGS;
- d307 1
- d331 1
- a331 1
- status = Fs_Open(fileName, flags, mode, &streamID);
- d344 1
- a344 1
- GetStats(&stats[0], (Time *) NULL);
- d354 1
- a354 1
- GetStats(&stats[nextStat], &time);
- d424 1
- a424 1
- Io_PrintStream(io_StdErr, "Lowticks=%u.\n", lowTicks);
- d441 1
- a441 1
- "OldStatsPtr->lowTicks=%u, newStatsPtr->lowTicks=%u.\n",
- d445 1
- a445 1
- "Idle ticks %d/%u => %6.2f%% Utilization, Queue length %d.\n",
- d480 2
- a481 1
- * returned in *statsPtr.
- d491 1
- a491 1
- GetStats(statsPtr, timePtr)
- d494 1
- d503 1
- d535 1
- a535 1
- OutputLoads(streamID, loads, time)
- d539 1
- d562 2
- a563 2
- "%2d %3d %10d %3.0f %3.0f %3.0f %5.2f %5.2f %5.2f\n",
- LA_RPC_UPDATE, hostID, time.seconds,
- d747 1
- a747 1
- "%3d %10d %d %d %d %lf %lf %lf",
- d750 1
- d757 1
- a757 1
- if (numScanned != 8) {
- d797 1
- a797 1
-
- d805 1
- a805 1
- "%3d %10d %3d %3d %3d %5.2lf %5.2lf %5.2lf\n",
- d808 1
- d871 1
- a871 1
- status = Fs_Open(fileName, (OPEN_WRITE_FLAGS | FS_NAMED_PIPE_OPEN),
- d925 1
- a925 1
- i++, utilPtr += UTIL_RECORD_SIZE) {
- d928 1
- a928 1
- "%*d %d %d %d %d %d %lf %lf %lf",
- d931 1
- d938 1
- a938 1
- if (numScanned != 8) {
- d940 1
- a940 1
- "Error scanning data for node %d. Scanned only %d items.\n",
- d948 1
- a948 1
- "Mismatch between counter (%d) and value in data file (%d).\n",
- d952 2
- a953 2
- Io_Print("Node %d\tload average %5.2lf.\n", hostID,
- nodeInfo.lengths[2]);
- d963 39
- @
-
-
- 1.6
- log
- @Changed weights to be exact values for 1, 5, and 15 minute averages.
- Maintain avg. ready-queue lengths. Wrote initial code for server
- process (using named pipes).
- @
- text
- @d1 1
- a1 1
- /*
- d13 1
- a13 1
- static char rcsid[] = "$Header: loadAvg.c,v 1.5 87/02/23 20:13:41 douglis Exp $ SPRITE (Berkeley)";
- d28 1
- d31 12
- d46 1
- a46 1
- #define LOAD_INTERVAL 5
- d48 2
- a49 2
- #define WEIGHT1 (double) 0.9200444146293232 /* exp(-1/12) */
- #define WEIGHT2 (double) 0.9834714538216174 /* exp(-1/60) */
- d51 3
- a53 3
- #define LOAD_NUM_VALUES 3
-
- /*
- d58 1
- a58 1
- #define OPEN_FLAGS (FS_WRITE | FS_CREATE)
- d63 2
- a64 2
- * A record contains "%3d %10d %3.0f %3.0f %3.0f %5.2f %5.2f %5.2f\n",
- * plus a null byte. (This amounts to 40 bytes.) Make it the next
- d70 2
- a71 2
- Boolean daemon = FALSE;
- Boolean server = FALSE;
- d75 2
- a76 2
- Boolean writeToDataFile = FALSE;
- Boolean writeToPipe = FALSE;
- d78 1
- a80 1
- Boolean ioTest = FALSE;
- d89 6
- a94 2
- {OPT_TRUE, 'd', (Address)&daemon,
- "Run as a daemon and report load information to the global server."},
- d97 1
- a97 1
- "Interval between iterations for getting load info (default 1 second)"},
- d100 8
- a107 8
- {OPT_TRUE, 'F', (Address)&forkChild, "Fork off the daemon."},
- {OPT_TRUE, 'f', (Address)&writeToDataFile,
- "Output options:\n\tOutput daemon's info to data file (DEFAULT)."},
- {OPT_TRUE, 'p', (Address)&writeToPipe,
- "\tOutput daemon's info to named pipe."},
- {OPT_TRUE, 's', (Address)&writeToStdOut,
- "\tOutput daemon's info to standard output."},
- {OPT_TRUE, 'l', (Address)&lockFile,
- d111 2
- d117 1
- a117 5
- {OPT_TRUE, 'S', (Address)&server,
- "Run as a daemon maintaining the global state."},
- {OPT_STRING, 'P', (Address)&pipeDir,
- "Directory containing named pipes (default \"/etc/daemons\")."},
- {OPT_STRING, 'w', (Address)&weightString,
- d124 1
- a124 1
- * at some instant in time.
- d143 1
- a143 1
- /*
- d149 2
- a150 1
- Load loads[LOAD_NUM_VALUES];
- d156 2
- a157 1
- void RunDaemon(), RunServer(), GetStats(), OutputLoads(), CalculateLoads();
- d199 3
- a201 14
- if (ioTest) {
- Io_Print("Testing: %3.0f %3.0f %3.0f %3.0f %3.0f ...\n",
- 0.0, 0.01, 0.001, 0.0001, 0.00001);
- status = Io_Error(io_StdOut);
- if (status != SUCCESS) {
- Stat_PrintMsg(status, "Error in Io_Print");
- Proc_Exit(status);
- }
- Io_Flush(io_StdOut);
- }
-
- if (! (writeToDataFile || writeToPipe || writeToStdOut)) {
- writeToDataFile = TRUE;
- } else if (AND3(writeToDataFile, writeToPipe, writeToStdOut)) {
- d203 1
- a203 1
- "%s: may only write to one of data-file/pipe/console.\n",
- d207 12
- a218 1
- if (lockFile && !writeToDataFile) {
- d235 5
- a239 1
- if (debug) {
- d249 2
- a250 2
-
- if (daemon) {
- d253 7
- d271 1
- a271 1
- * pipes.
- d293 1
- a293 1
- int flags = OPEN_FLAGS;
- d310 2
- a311 2
- if (writeToDataFile || writeToPipe) {
- if (writeToDataFile) {
- d334 1
- a334 1
-
- d455 1
- a455 1
- (1 - weights[i]) * newStatsPtr->queueLength;
- d500 1
- a500 1
-
- d541 1
- d546 2
- a547 1
-
- d549 4
- a552 3
- "%3d %10d %3.0f %3.0f %3.0f %5.2f %5.2f %5.2f\n",
- hostID, time.seconds, loads[0].utilization * 100,
- loads[1].utilization * 100, loads[2].utilization * 100,
- d554 2
- a555 2
- loads[2].queueLength);
-
- d563 1
- a563 1
- if (writeToDataFile) {
- a613 1
- NodeInfo info;
- d621 1
- d624 1
- a624 1
- int timestamp;
- d673 2
- a674 1
- numScanned = Io_ScanString(buffer, "%3d", &hostID);
- d677 2
- a678 1
- "Error scanning hostID from request pipe.\n");
- d681 5
- a685 4
- if (hostID > 0) {
- if (hostID >= MAX_NUM_HOSTS) {
- Io_PrintStream(io_StdErr, "Invalid hostID: %d.\n", hostID);
- Proc_Exit(FAILURE);
- d687 7
- a693 13
- numScanned = Io_ScanString(&buffer[4],
- "%10d %3.0f %3.0f %3.0f %5.2f %5.2f %5.2f",
- &info.timestamp,
- &info.loads[0].utilization,
- &info.loads[1].utilization,
- &info.loads[2].utilization,
- &info.loads[0].queueLength,
- &info.loads[1].queueLength,
- &info.loads[2].queueLength);
- if (numScanned != 7) {
- Io_PrintStream(io_StdErr,
- "Error scanning information from request pipe.\n");
- Proc_Exit(FAILURE);
- d695 3
- a697 5
- nodeInfo[hostID] = info;
- } else {
- if (debug) {
- Io_PrintStream(io_StdErr,
- "Received request for idle node.\n");
- a698 14
- for (i = 0; i < MAX_NUM_HOSTS; i++) {
- if (nodeInfo[i].timestamp != NIL) {
- Io_PrintStream(io_StdErr,
- "3d %10d %3.0f %3.0f %3.0f %5.2f %5.2f %5.2f\n",
- i,
- nodeInfo[i].timestamp,
- nodeInfo[i].loads[0].utilization,
- nodeInfo[i].loads[1].utilization,
- nodeInfo[i].loads[2].utilization,
- nodeInfo[i].loads[0].queueLength,
- nodeInfo[i].loads[1].queueLength,
- nodeInfo[i].loads[2].queueLength);
- }
- }
- d706 241
- @
-
-
- 1.5
- log
- @use exponential decay w/ period of 1 second.
- @
- text
- @d13 1
- a13 1
- static char rcsid[] = "$Header: loadAvg.c,v 1.4 87/02/19 15:47:20 douglis Exp $ SPRITE (Berkeley)";
- d27 1
- d29 3
- a31 5
- #define LOAD_INTERVAL 1
- #define WEIGHT1 (double) .2
- #define WEIGHT2 (double) .9
- #define WEIGHT3 (double) .99
- #define LOAD_NUM_VALUES 3
- d33 11
- d47 1
- d50 3
- a52 1
- * A record contains "%3d %10d %3.0f %3.0f %3.0f\n", plus a null byte.
- d55 1
- a55 1
- #define UTIL_RECORD_SIZE (4 + 11 + (LOAD_NUM_VALUES * 4) + 1)
- d58 1
- d60 2
- d76 2
- a77 1
- {OPT_TRUE, 'd', (Address)&daemon, "Run as a daemon and report load information to the global server."},
- d79 4
- a91 2
- {OPT_TRUE, 'I', (Address)&ioTest,
- "Do a silly test of Io_Print."},
- d98 2
- d107 5
- d118 20
- d140 1
- a140 1
- void RunDaemon(), GetStats(), OutputLoads(), CalculateLoads();
- d260 1
- a260 1
- double loads[LOAD_NUM_VALUES];
- d269 2
- d279 1
- a279 1
- sleepTime.seconds = LOAD_INTERVAL;
- d313 2
- d320 4
- a323 1
- OutputLoads(streamID, loads, time);
- d342 2
- a343 1
- * the utilization of the computer during that period of time.
- d345 2
- d348 2
- a349 2
- * The calculated utilization is returned in
- * loadsPtr[0..LOAD_NUM_VALUES].
- d361 1
- a361 1
- double loads[];
- d408 1
- a408 1
- "Idle ticks %d/%u => %6.2f%% Utilization.\n",
- d411 2
- a412 1
- currentLoad * 100);
- d419 2
- a420 1
- loads[i] = currentLoad;
- d424 1
- a424 1
- loads[i] = weights[i] * loads[i] +
- d426 2
- d463 1
- a463 3
- #ifdef READY_QUEUE
- statsPtr->queueLength = stats.queueLength;
- #endif READY_QUEUE
- d497 1
- a497 1
- double loads[];
- d503 1
- a503 1
- char utilRecord[UTIL_RECORD_SIZE];
- d507 6
- d518 6
- a523 3
- Io_PrintString(utilRecord, "%3d %10d %3d %3d %3d\n",
- hostID, time.seconds, (int) (loads[0] * 100),
- (int) (loads[1] * 100), (int) (loads[2] * 100));
- a532 5
- if (!init) {
- init = TRUE;
- args.base = IOC_BASE_ZERO;
- args.offset = hostID * UTIL_RECORD_SIZE;
- }
- d558 136
- @
-
-
- 1.4
- log
- @fixed problem w/ filename for named pipe.
- @
- text
- @d13 1
- a13 1
- static char rcsid[] = "$Header: loadAvg.c,v 1.2 87/02/15 22:31:46 douglis Exp $ SPRITE (Berkeley)";
- d28 5
- a32 7
- #define LOAD_INTERVAL 5
- #define LOAD_NUM_INTS_1 1
- #define LOAD_NUM_INTS_2 2
- #define LOAD_NUM_INTS_3 10
- #define LOAD_NUM_INTERVALS LOAD_NUM_INTS_3
- static int loadIntervals[] = {1, 2, LOAD_NUM_INTERVALS};
- #define LOAD_NUM_VALUES (sizeof(loadIntervals) / sizeof(int))
- d51 1
- d56 2
- d71 2
- d81 2
- d89 2
- a90 2
- Time time;
- } UtilInfo;
- d94 1
- a94 1
- void RunDaemon(), GetIdleTicks(), OutputUtil();
- d96 1
- a96 2
- static unsigned int idleTicksPerSecond;
- double CalculateUtil();
- d112 1
- a112 1
- * Variable.
- d123 1
- d136 10
- d157 1
- a157 1
- "%s: may only specify lock (-l) option if writing to a data file.",
- d161 16
- a176 1
-
- d195 1
- a195 1
- * Fork off a child to be the local daemon. This daemon will
- d203 1
- a203 1
- * A second process is created.
- a211 2
- UtilInfo utilArray[LOAD_NUM_INTERVALS];
- UtilInfo latestInfo;
- d213 2
- a214 4
- int i;
- int matchingInterval;
- double utils[LOAD_NUM_VALUES];
- int currentInterval;
- d221 2
- a230 7
- for (i = 0; i < LOAD_NUM_INTERVALS; i++) {
- utilArray[i].lowTicks = 0;
- utilArray[i].highTicks = NIL;
- utilArray[i].time = time_ZeroSeconds;
- }
- GetIdleTicks(&utilArray[0]);
- currentInterval = 1;
- d254 12
- d267 4
- a274 21
- GetIdleTicks(&latestInfo);
- for (i = 0; i < LOAD_NUM_VALUES; i++) {
- matchingInterval = (currentInterval - loadIntervals[i] +
- LOAD_NUM_INTERVALS) % LOAD_NUM_INTERVALS;
- if (utilArray[matchingInterval].highTicks != NIL) {
- if (debug) {
- Io_PrintStream(io_StdErr,
- "%d-second average utilization:",
- loadIntervals[i] * LOAD_INTERVAL);
- Io_Flush(io_StdErr);
- }
-
- utils[i] = CalculateUtil(&utilArray[matchingInterval],
- &latestInfo);
- } else {
- utils[i] = utils[i-1];
- }
- }
- OutputUtil(streamID, utils, latestInfo.time);
- utilArray[currentInterval] = latestInfo;
- currentInterval = (currentInterval + 1) % LOAD_NUM_INTERVALS;
- d286 1
- a286 1
- * CalculateUtil --
- d292 2
- a293 1
- * The calculated utilization is returned.
- d301 5
- a305 4
- double
- CalculateUtil(oldInfoPtr, newInfoPtr)
- UtilInfo *oldInfoPtr;
- UtilInfo *newInfoPtr;
- d307 6
- a312 4
- Time timeDiff;
- double util;
- double maxIdle;
- register unsigned highTicks, lowTicks;
- d314 6
- a319 4
- highTicks = newInfoPtr->highTicks - oldInfoPtr->highTicks;
- lowTicks = newInfoPtr->lowTicks - oldInfoPtr->lowTicks;
- if (highTicks != 0) {
- lowTicks = ((int) lowTicks) + HIGH_TO_LOW_TICKS;
- d321 6
- d328 1
- d331 1
- a331 1
- Io_PrintStream(io_StdErr, "Lowticks=%d.\n", lowTicks);
- d334 11
- a344 5
- Time_Subtract(newInfoPtr->time, oldInfoPtr->time, &timeDiff);
- maxIdle = idleTicksPerSecond * ((double) timeDiff.seconds +
- ((double) timeDiff.microseconds) / 1000000.);
-
- util = ((double)lowTicks)/maxIdle;
- d348 2
- a349 3
- "OldInfoPtr->lowTicks=%d, newInfoPtr->lowTicks=%d, time = (%d,%d).\n",
- oldInfoPtr->lowTicks, newInfoPtr->lowTicks,
- timeDiff.seconds, timeDiff.microseconds);
- d352 1
- a352 1
- "Idle ticks %d/%5.0f = %6.2f%% Idle.\n",
- d355 2
- a356 1
- util * 100);
- d358 12
- a369 2
- Io_Flush(io_StdErr);
- return(util);
- d376 1
- a376 1
- * GetIdleTicks --
- d378 2
- a379 1
- * Get the current number of idle ticks and the time.
- d382 2
- a383 1
- * The number of ticks and time are returned in *utilPtr.
- d386 2
- a387 1
- * None.
- d393 3
- a395 2
- GetIdleTicks(utilPtr)
- UtilInfo *utilPtr;
- d398 1
- d401 5
- a405 3
- utilPtr->lowTicks = stats.idleTicksLow;
- utilPtr->highTicks = stats.idleTicksOverflow;
- Sys_GetTimeOfDay(&(utilPtr->time), NULL, NULL);
- d407 8
- a414 1
- idleTicksPerSecond = stats.idleTicksPerSecond;
- d421 1
- a421 1
- * OutputUtil --
- d437 1
- a437 1
- OutputUtil(streamID, utils, time)
- d439 1
- a439 1
- double utils[];
- d450 1
- a450 1
- Io_PrintStream(io_StdErr, "OutputUtil: streamID = %d.\n", streamID);
- d454 3
- a456 3
- Io_PrintString(utilRecord, "%3d %10d %3.0f %3.0f %3.0f\n",
- hostID, time.seconds,
- utils[0] * 100, utils[1] * 100, utils[2] * 100);
- d495 1
- @
-
-
- 1.3
- log
- @Allow writing data to single data file, named pipe, or stdout.
- @
- text
- @d192 1
- d217 2
- a218 1
- fileName = requestFile;
- @
-
-
- 1.2
- log
- @Currently works to the extent of printing out idle times on the
- console. Fs_Lock call bombs, so can't use a file yet.
- @
- text
- @d13 1
- a13 1
- static char rcsid[] = "$Header: loadAvg.c,v 1.1 87/02/15 20:53:15 douglis Exp $ SPRITE (Berkeley)";
- d37 2
- a38 2
- #define REQUEST_FLAGS (FS_WRITE | FS_CREATE)
- #define REQUEST_MODE 0664
- d41 1
- a41 2
- * A record contains "%3d " for each value (i.e., 4 characters), plus "%10d"
- * for the time, plus a null byte.
- d44 1
- a44 1
- #define UTIL_RECORD_SIZE ((LOAD_NUM_VALUES * 4) + 11)
- d48 3
- a50 1
- Boolean writeToFile = TRUE;
- d52 1
- d56 1
- d61 17
- a77 5
- {OPT_TRUE, 'f', (Address)&forkChild, "Fork off the daemon."},
- {OPT_FALSE, 'F', (Address)&writeToFile,
- "Do not output daemon's info to file."},
- {OPT_STRING, 'r', (Address)&requestFile, "Request file name\n"},
- {OPT_STRING, 'R', (Address)&responseFile, "Response file name\n"},
- d88 1
- d126 21
- d190 4
- a193 1
- int requestID;
- d195 1
- d212 7
- a218 1
- if (writeToFile) {
- d220 1
- a220 1
- Io_PrintStream(io_StdErr, "Opening file %s.\n", requestFile);
- d223 1
- a223 2
- status = Fs_Open(requestFile, REQUEST_FLAGS, REQUEST_MODE,
- &requestID);
- d229 1
- a229 1
- requestID = STANDARD_OUTPUT;
- d254 1
- a254 1
- OutputUtil(requestID, utils, latestInfo.time);
- d383 1
- a383 1
- int oldOffset; /* ignored */
- a384 1
- int i;
- d393 2
- a394 1
- Io_PrintString(utilRecord, "%10d %3.0f %3.0f %3.0f", time.seconds,
- d397 1
- a397 1
- if (streamID != STANDARD_OUTPUT) {
- d403 2
- d415 13
- a427 2
- status = Fs_Write(streamID, UTIL_RECORD_SIZE, utilRecord,
- &bytesWritten);
- a428 9
- Stat_PrintMsg(status, "Error in Fs_Read");
- Proc_Exit(status);
- }
- if (bytesWritten != UTIL_RECORD_SIZE) {
- Io_PrintStream(io_StdErr, "Only %d bytes written.\n", bytesWritten);
- Proc_Exit(FAILURE);
- }
- status = Fs_Lock(streamID, FS_UNLOCK);
- if (status != SUCCESS) {
- a429 8
- Proc_Exit(status);
- }
- } else {
- Io_Print("%s\n", utilRecord);
- Io_Flush(io_StdOut);
- status = Io_Error(io_StdOut);
- if (status != SUCCESS) {
- Stat_PrintMsg(status, "Error in Io_Print");
- @
-
-
- 1.1
- log
- @Initial revision
- @
- text
- @d13 1
- a13 1
- static char rcsid[] = "$Header: proto.c,v 1.7 87/01/04 17:28:48 andrew Exp $ SPRITE (Berkeley)";
- d37 2
- d40 7
- d50 1
- d58 1
- d73 1
- a73 1
- void RunDaemon(), GetIdleTicks();
- d153 1
- d155 1
- a155 1
- if (!debug) {
- d172 4
- d183 3
- a185 3
- streamID = STANDARD_OUTPUT;
-
- while(TRUE) {
- a206 1
- OutputUtil(requestID, utils, latestInfo.time);
- d208 1
- d335 56
- @
-